import type { App } from 'vue'
import type { TypeItem, FxCommonType } from '@/config/app_type'
import COMMON_TYPE_CONFIG from '@/config/app_type'
import type { BillGenerateField } from '@/config/common_type_config/type'
import type { BillFieldTypeKey } from '@/config/bill_field_edit_config'
import BILL_FIELD_EDIT_CONFIG from '@/config/bill_field_edit_config'
import utils from '@/js/utils'
const log = (msg: string) => {
	return utils.fxDebug('typeMiddleware')(msg)
}
type PartialTypeItem = Partial<TypeItem>
type GetCommonItem<K extends keyof FxCommonType> = FxCommonType[K][number]
// 获取类型list by shw
const getCommonTypeList = <K extends keyof FxCommonType> (type: K): GetCommonItem<K>[] => {
	if (!COMMON_TYPE_CONFIG[type]) {
		log('无法找到要查询类型,请检查type值是否传输正确')
	}
	return COMMON_TYPE_CONFIG[type]
}
// 根据类型id获取类型数据对象 by shw
const getCommonTypeObjectById = <K extends keyof FxCommonType> (type: K) => {
	return (id: string): GetCommonItem<K> => {
		return getCommonTypeList(type).find(item => {
			return `${item.id}` === `${id}`
		}) || {} as GetCommonItem<K>
	}
}
/**
 * @name getCommonTypeItemByRule
 * @desc 根据类型rule获取类型数据对象
 * @author shw
 * @date 2021/9/10
 * @param {String} type 类型名称
 * @param {Boolean} mulity  mulity=false只返回找到的第一个符合规则的类型, 否则返回所有
 * @return object / array
 */
const getCommonTypeItemByRule = <K extends keyof FxCommonType> (type: K, mulity = false) => {
	return (...arg: (string | object)[]) => {
		const typeList = getCommonTypeList(type)
		if (!mulity) {
			return [typeList.find(item => {
				if ('rule' in item) {
					return (item.rule as Function)(...arg)
				}
				return false
			}) || {}]
		} else {
			return typeList.filter(item => {
				if ('rule' in item) {
					return (item.rule as Function)(...arg)
				}
				return false
			})
		}
	}
}

// 类型判断 by shw
const isCommonType = <K extends keyof FxCommonType> (typeModule: K, rule = 'id') => {
	return (typeName = []) => {
		return (...arg: string[]) => {
			const types: string[] = [].concat(typeName)
			if (rule === 'id') {
				const typeValue = (getCommonTypeObjectById(typeModule)(arg[0]) as TypeItem).type
				return types.includes(typeValue as string)
			} else {
				const typeValues = getCommonTypeItemByRule(typeModule, true)(...arg).map(item => (item as TypeItem).type)
				return types.some(item => typeValues.includes(item))
			}
		}
	}
}
/**
 * @name getBillGenerateTypeObject
 * @desc 获取单据生成类型数据对象
 * @author shw
 * @date 2023/2/6
 * @param {string} billType 单据对象
 * @param {object} orderDetail 单据对象
 * @return object (单据类型对象)
 */
const getBillGenerateSubTypeObject = <T extends keyof FxCommonType> (billGenerateType: T, billGenerateField: BillGenerateField) => {
	return getCommonTypeItemByRule(billGenerateType)(billGenerateField)
}
export const getFieldEditEnable = (billGenerateType: BillFieldTypeKey, field: string, billGenerateField: BillGenerateField): boolean => {
	const billTypeKey = BILL_FIELD_EDIT_CONFIG[billGenerateType].billTypeKey as keyof FxCommonType
	const billSubType = getBillGenerateSubTypeObject(billTypeKey, billGenerateField)[0]
	if (!('id' in billSubType)) {
		return false
	}
	const billTypeId = ((billSubType as PartialTypeItem).id) as string
	if (!(billTypeId in BILL_FIELD_EDIT_CONFIG[billGenerateType].billField)) {
		log(`未配置单据类型${billTypeId}的可编辑字段,请进行正确配置`)
		return false
	}
	if (!(field in BILL_FIELD_EDIT_CONFIG[billGenerateType].billField[billTypeId])) {
		log(`未配置单据类型${billTypeId}的可编辑字段-${field},请进行正确配置`)
	}
	return BILL_FIELD_EDIT_CONFIG[billGenerateType].billField[billTypeId][field]
}
export type TypeMiddleware = Record<string, Function>
const typeMiddleware = {
	getCommonTypeList,
	getCommonTypeObjectById,
	getCommonTypeItemByRule,
	isCommonType,
	getFieldEditEnable
}
const install = (app: App): void => {
	app.config.globalProperties.$fxTypeMiddleware = typeMiddleware
}
export default {
	install,
	...typeMiddleware
}
